home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / GAMES / C014.ZIP / LARN_SRC.ZIP / SPHERES.C < prev    next >
C/C++ Source or Header  |  1993-11-17  |  7KB  |  183 lines

  1. /*
  2.   newsphere(x,y,dir,lifetime)  Function to create a new sphere of annihilation
  3.   rmsphere(x,y)      Function to delete a sphere of annihilation from list
  4.   sphboom(x,y)       Function to perform the effects of a sphere detonation
  5.   movsphere()        Function to look for and move spheres of annihilation
  6. */
  7. #include "header.h"
  8. #include "larndefs.h"
  9. #include "monsters.h"
  10. #include "objects.h"
  11. #include "player.h"
  12.  
  13. #define min(x,y) (((x)>(y))?(y):(x))
  14. #define max(x,y) (((x)>(y))?(x):(y))
  15.  
  16. /*
  17.  *  newsphere(x,y,dir,lifetime)  Function to create a new sphere of annihilation
  18.  *      int x,y,dir,lifetime;
  19.  *
  20.  *  Enter with the coordinates of the sphere in x,y
  21.  *    the direction (0-8 diroffx format) in dir, and the lifespan of the
  22.  *    sphere in lifetime (in turns)
  23.  *  Returns the number of spheres currently in existence
  24.  */
  25. newsphere(x,y,dir,life)
  26.     int x,y,dir,life;
  27.     {
  28.     int m;
  29.     struct sphere *sp;
  30.     if (((sp=(struct sphere *)malloc(sizeof(struct sphere)))) == 0)
  31.         return(c[SPHCAST]); /* can't malloc, therefore failure */
  32.     if (dir>=9) dir=0;  /* no movement if direction not found */
  33.     if (level==0) vxy(&x,&y);   /* don't go out of bounds */
  34.     else
  35.         {
  36.         if (x<1) x=1;  if (x>=MAXX-1) x=MAXX-2;
  37.         if (y<1) y=1;  if (y>=MAXY-1) y=MAXY-2;
  38.         }
  39.     if ((m=mitem[x][y]) >= DEMONLORD+4) /* demons dispel spheres */
  40.         {
  41.         show1cell(x,y);     /* show the demon (ha ha) */
  42.         cursors(); lprintf("\nThe %s dispels the sphere!",monster[m].name);
  43.         beep(); rmsphere(x,y);  /* remove any spheres that are here */
  44.         return(c[SPHCAST]);
  45.         }
  46.     if (m==DISENCHANTRESS) /* disenchantress cancels spheres */
  47.         {
  48.         cursors(); lprintf("\nThe %s causes cancellation of the sphere!",monster[m].name); beep();
  49. boom:   sphboom(x,y);   /* blow up stuff around sphere */
  50.         rmsphere(x,y);  /* remove any spheres that are here */
  51.         return(c[SPHCAST]);
  52.         }
  53.     if (c[CANCELLATION]) /* cancellation cancels spheres */
  54.         {
  55.         cursors(); lprcat("\nAs the cancellation takes effect, you hear a great earth shaking blast!"); beep();
  56.         goto boom;
  57.         }
  58.     if (item[x][y]==OANNIHILATION) /* collision of spheres detonates spheres */
  59.         {
  60.         cursors(); lprcat("\nTwo spheres of annihilation collide! You hear a great earth shaking blast!"); beep();
  61.         rmsphere(x,y);
  62.         goto boom;
  63.         }
  64.     if (playerx==x && playery==y) /* collision of sphere and player! */
  65.         {
  66.         cursors();
  67.         lprcat("\nYou have been enveloped by the zone of nothingness!\n");
  68.         beep(); rmsphere(x,y);  /* remove any spheres that are here */
  69.         nap(4000);  died(258);
  70.         }
  71.     item[x][y]=OANNIHILATION;  mitem[x][y]=0;  know[x][y]=1;
  72.     show1cell(x,y); /* show the new sphere */
  73.     sp->x=x;  sp->y=y;  sp->lev=level;  sp->dir=dir;  sp->lifetime=life;  sp->p=0;
  74.     if (spheres==0) spheres=sp; /* if first node in the sphere list */
  75.     else    /* add sphere to beginning of linked list */
  76.         {
  77.         sp->p = spheres;    spheres = sp;
  78.         }
  79.     return(++c[SPHCAST]);   /* one more sphere in the world */
  80.     }
  81.  
  82. /*
  83.  *  rmsphere(x,y)       Function to delete a sphere of annihilation from list
  84.  *      int x,y;
  85.  *
  86.  *  Enter with the coordinates of the sphere (on current level)
  87.  *  Returns the number of spheres currently in existence
  88.  */
  89. rmsphere(x,y)
  90.     int x,y;
  91.     {
  92.     register struct sphere *sp,*sp2=0;
  93.     for (sp=spheres; sp; sp2=sp,sp=sp->p)
  94.       if (level==sp->lev)   /* is sphere on this level? */
  95.         if ((x==sp->x) && (y==sp->y))   /* locate sphere at this location */
  96.             {
  97.             item[x][y]=mitem[x][y]=0;  know[x][y]=1;
  98.             show1cell(x,y); /* show the now missing sphere */
  99.             --c[SPHCAST];   
  100.             if (sp==spheres) { sp2=sp; spheres=sp->p; free((char*)sp2); }
  101.             else
  102.                 { sp2->p = sp->p;  free((char*)sp); }
  103.             break;
  104.             }
  105.     return(c[SPHCAST]); /* return number of spheres in the world */
  106.     }
  107.  
  108. /*
  109.  *  sphboom(x,y)    Function to perform the effects of a sphere detonation
  110.  *      int x,y;
  111.  *
  112.  *  Enter with the coordinates of the blast, Returns no value
  113.  */
  114. static sphboom(x,y)
  115.     int x,y;
  116.     {
  117.     register int i,j;
  118.     if (c[HOLDMONST]) c[HOLDMONST]=1;
  119.     if (c[CANCELLATION]) c[CANCELLATION]=1;
  120.     for (j=max(1,x-2); j<min(x+3,MAXX-1); j++)
  121.       for (i=max(1,y-2); i<min(y+3,MAXY-1); i++)
  122.         {
  123.         item[j][i]=mitem[j][i]=0;
  124.         show1cell(j,i);
  125.         if (playerx==j && playery==i)
  126.             {
  127.             cursors(); beep();
  128.             lprcat("\nYou were too close to the sphere!");
  129.             nap(3000);
  130.             died(283); /* player killed in explosion */
  131.             }
  132.         }
  133.     }
  134.  
  135. /*
  136.  *  movsphere()     Function to look for and move spheres of annihilation
  137.  *
  138.  *  This function works on the sphere linked list, first duplicating the list
  139.  *  (the act of moving changes the list), then processing each sphere in order
  140.  *  to move it.  They eat anything in their way, including stairs, volcanic
  141.  *  shafts, potions, etc, except for upper level demons, who can dispel
  142.  *  spheres.
  143.  *  No value is returned.
  144.  */
  145. #define SPHMAX 20   /* maximum number of spheres movsphere can handle */
  146. movsphere()
  147.     {
  148.     register int x,y,dir,len;
  149.     register struct sphere *sp,*sp2;
  150.     struct sphere sph[SPHMAX];
  151.  
  152.     /* first duplicate sphere list */
  153.     for (sp=0,x=0,sp2=spheres; sp2; sp2=sp2->p) /* look through sphere list */
  154.       if (sp2->lev == level)    /* only if this level */
  155.         {
  156.         sph[x] = *sp2;  sph[x++].p = 0;  /* copy the struct */
  157.         if (x>1)  sph[x-2].p = &sph[x-1]; /* link pointers */
  158.         }
  159.     if (x) sp= sph; /* if any spheres, point to them */
  160.         else return;    /* no spheres */
  161.  
  162.     for (sp=sph; sp; sp=sp->p)  /* look through sphere list */
  163.         {
  164.         x = sp->x;    y = sp->y;
  165.         if (item[x][y]!=OANNIHILATION) continue;    /* not really there */
  166.         if (--(sp->lifetime) < 0)   /* has sphere run out of gas? */
  167.             {
  168.             rmsphere(x,y); /* delete sphere */
  169.             continue;
  170.             }
  171.         switch(rnd((int)max(7,c[INTELLIGENCE]>>1))) /* time to move the sphere */
  172.             {
  173.             case 1:
  174.             case 2:     /* change direction to a random one */
  175.                         sp->dir = rnd(8);
  176.             default:    /* move in normal direction */
  177.                         dir = sp->dir;      len = sp->lifetime;
  178.                         rmsphere(x,y);
  179.                         newsphere(x+diroffx[dir],y+diroffy[dir],dir,len);
  180.             };
  181.         }
  182.     }
  183.